#include "base/base_tracker.h"
#include "base/base_android_log_utils.h"
#include "sstream"

/// 架构引入头定义
#if defined(__arm__) && !defined(__aarch64__)
/// arm 32引入头
#include "armeabi-v7a/tracker.h"

#elif defined(__aarch64__)
/// arm 64引入头
#include "arm64-v8a/tracker.h"
#else
#error "Unsupported architecture"
#endif

#define TAG_LOG "tracker_manager"

static BaseTracker *signalTracker = new Tracker();

extern "C"
{
    /// 需要跑在 main isolate 上，否则应该抛出错误
    void registerSignalListenInMainIsolate()
    {
        if (signalTracker)
        {
            Logger::logInfo(TAG_LOG, "cpp tracker init, register signal listener...");
            signalTracker->unregisterSignalListener();
            signalTracker->registerSignalListener();
        }
        else
        {
            signalTracker = new Tracker();
            signalTracker->unregisterSignalListener();
            signalTracker->registerSignalListener();
        }
    }
    /// @brief 进行堆栈侦测，随便的isolate上
    void sendTrackSignal()
    {
        if (signalTracker)
        {
            Logger::logInfo(TAG_LOG, "tracker do track...");
            signalTracker->track();
        }
    }

    /// 设置堆栈的dart基地址以及vm地址
    void
    sendTrackSignalWithBaseIsolateInstructions(int64_t isolateInstructions, int64_t vmInstructions)
    {
        if (signalTracker)
        {
            std::stringstream ss;
            ss << "tracker do track...." << "isolateInstructions: " << isolateInstructions << std::endl;
            Logger::logInfo(TAG_LOG, ss.str().c_str());
            signalTracker->setBaseIsolateInstructions(isolateInstructions, vmInstructions);
            signalTracker->track();
        }
    }

    /// 设置堆栈文件存储路径
    void setTrackStackSavePath(const char* savePath)
    {
        if (signalTracker)
        {
            std::string filePath(savePath);
            signalTracker->setTrackStaceSavePath(filePath);
        }
    }

    /// @brief 释放cpp的tracker
    void releaseTracker()
    {
        std::string msg = "tracker address: ";
        msg.append(std::to_string((long)std::addressof(signalTracker)));
        msg.append("tracker is nullptr?: ").append(std::to_string(signalTracker == nullptr));
        Logger::logInfo(TAG_LOG, msg.c_str());

        if (signalTracker)
        {
            Logger::logInfo(TAG_LOG, "cpp tracker release");
            delete signalTracker;
            signalTracker = nullptr;
        }
    }

    void androidLogger(const char *logger, int length)
    {
        Logger::logInfo(TAG_LOG, logger);
    }
}